
#openocd 脚本
#   操作daplink来处理目标板JTAG, 读取外挂flash

# 重置命令
irscan AG10K.tap 0x3e3 -endstate RUN/IDLE

# 处理一些数据
irscan AG10K.tap 0x3f8 -endstate RUN/IDLE
irscan AG10K.tap 0x3fc -endstate RUN/IDLE
drscan AG10K.tap 8 0xf0 -endstate RUN/IDLE
irscan AG10K.tap 0x3fd -endstate RUN/IDLE
# 读取目标flash  0x700000c0 是spi flash的tdi时序.spi是大端,而jtag的dr是小端.
#       所以, 0xc0=0x3 (cmd:read), 0x7=0x3 (addr:0x3)
puts "read flash"
set val [drscan AG10K.tap 128 0x700000c0 -endstate RUN/IDLE]
puts ${val}
puts "read ID"
# 以下是RDID命令, 0xF9=0x9f (cmd:RDID)
set val [drscan AG10K.tap 128 0x000000F9 -endstate RUN/IDLE]
puts ${val}

proc toMSB {args} {
    #转换成
    set b0 [expr {((($args)&0x80)!=0)<<0}]
    set b1 [expr {((($args)&0x40)!=0)<<1}]
    set b2 [expr {((($args)&0x20)!=0)<<2}]
    set b3 [expr {((($args)&0x10)!=0)<<3}]

    set b4 [expr {((($args)&0x8)!=0)<<4}]
    set b5 [expr {((($args)&0x4)!=0)<<5}]
    set b6 [expr {((($args)&0x2)!=0)<<6}]
    set b7 [expr {((($args)&0x1)!=0)<<7}]

    set bit [expr {$b0 + $b1 + $b2 + $b3 + $b4 + $b5 + $b6 + $b7}]
    return $bit;
}

proc toMSB16 {args} {
    set hex1 [expr {($args>>0)&0xff}]
    set hex2 [expr {($args>>8)&0xff}]

    set hex1 [toMSB $hex1]
    set hex2 [toMSB $hex2]

    set hex [expr {($hex1<<8)|$hex2}]
    return $hex;
}

proc toMSB24 {args} {
    set hex1 [expr {($args>>0)&0xff}]
    set hex2 [expr {($args>>8)&0xffff}]

    set hex1 [toMSB $hex1]
    set hex2 [toMSB16 $hex2]

    set hex [expr {($hex1<<16)|$hex2}]
    return $hex;
}

proc toMSB32 {args} {
    set hex1 [expr {($args>>0) &0xffff}]
    set hex2 [expr {($args>>16)&0xffff}]

    set hex1 [toMSB16 $hex1]
    set hex2 [toMSB16 $hex2]

    set hex [expr {($hex1<<16)|$hex2}]
    return $hex;
}

# SFDP 5A
# set val [drscan AG10K.tap 896 [toMSB 0x5a] -endstate RUN/IDLE]
# puts ${val}

if {0} {
    #需要关闭 "Warn"
    set old_debug_level [debug_level] ;set e "";set old_debug_level [regsub ":" $old_debug_level $e]
    # debug_level 0
    set val [drscan AG10K.tap 32 [toMSB 0x5a] -endstate DRSHIFT]
    puts ${val}
    set val [drscan AG10K.tap 32 [toMSB 0] -endstate DRSHIFT]
    puts ${val}
    set val [drscan AG10K.tap 32 [toMSB 0] -endstate DRSHIFT]
    puts ${val}
    set val [drscan AG10K.tap 32 [toMSB 0] -endstate DRSHIFT]
    puts ${val}
    set val [drscan AG10K.tap 32 [toMSB 0] -endstate RUN/IDLE]
    puts ${val}
    eval $old_debug_level
}

set val [drscan AG10K.tap 128 [toMSB 0x5a] -endstate RUN/IDLE]
puts ${val}

proc hex_to_byte {hex {pos 0}} {
    set len [string length $hex]
    set len [expr {$len-1}]
    set arr {}
    while {[expr {$len>=0}]} {
        set h [string range $hex $len-1 $len]
        # puts输出测试
        # puts $h
        set b [toMSB 0x$h]
        if [expr {$pos<=0}] {
            lappend arr $b
        }
        incr pos -1
        # 下面是转换后的输出测试
        # puts [format "%02x" $b]
        incr len -2
    }
    return $arr
}

proc sflash_cmd {cmd addr len} {
    set send_data [format "0x%x" [expr {[toMSB $cmd]+([toMSB24 $addr]<<8)}]];
    # puts $send_data
    set val [drscan AG10K.tap $len $send_data -endstate RUN/IDLE]
    return $val;
}

# 与sflash_cmd 不同的是,cmd结束后停留在DRSHIFT
proc sflash_cmd_cc {cmd addr len} {
    set send_data [format "0x%x" [expr {[toMSB $cmd]+([toMSB24 $addr]<<8)}]];
    # puts "$len $send_data"
    set val [drscan AG10K.tap $len $send_data -endstate DRSHIFT]
    return $val;
}

proc sflash_send32 {data {endstate DRSHIFT} } {
    set hex0 [toMSB [expr {($data>>0)&0xff}]];
    set hex1 [toMSB [expr {($data>>8)&0xff}]];
    set hex2 [toMSB [expr {($data>>16)&0xff}]];
    set hex3 [toMSB [expr {($data>>24)&0xff}]];

    set send_data [format "0x%02x%02x%02x%02x" $hex3 $hex2 $hex1 $hex0]
    # puts "s:$send_data"
    # set val [drscan AG10K.tap 32 $send_data -endstate DRSHIFT]
    set val [drscan AG10K.tap 32 $send_data -endstate $endstate]
    return $val;
}

proc sflash_send {data len} {
    set send_data [format "0x%x" [toMSB32 $data]]
    set val [drscan AG10K.tap $len $send_data -endstate DRSHIFT]
    return $val;
}

proc slfash_send_end {data len} {
    set val [sflash_send32 $data RUN/IDLE]
    return $val;
}

proc sflash_erase {addr} {
    sflash_cmd 0x6 0x0 8
    sflash_cmd 0x81 $addr 32
    # 有些flash需要等待擦除,500的失败了,1000成功
    runtest 1000
    sflash_cmd 0x4 0x0 8
}

proc sflash_read {addr len} {
    set vv [sflash_cmd 0x3 $addr [expr ($len+1)*8+32]]
    return $vv
}

proc sflash_program_begin {addr} {
    # 0x6命令开启编程
    sflash_cmd 0x6 0x0 8
    runtest 10
    # 输出为 status :2 为正确
    # puts "status :[hex_to_byte [sflash_cmd 0x5 0x0 40] 4]"
    sflash_cmd_cc 0x2 $addr 32
}

proc sflash_program_end {end_dat} {
    # pathmove RUN/IDLE
    slfash_send_end $end_dat 32
    runtest 1000
    sflash_cmd 0x4 0x0 8
    # 0x4关闭编程
    # 输出为0为正确
    puts "status end:[hex_to_byte [sflash_cmd 0x5 0x0 40] 4]"
}

proc sflash_program_page {addr page1 page2 page3 page4} {
    sflash_erase $addr
    sflash_program_begin $addr
    set val1 [drscan AG10K.tap 512 $page1 -endstate DRSHIFT]
    set val2 [drscan AG10K.tap 512 $page2 -endstate DRSHIFT]
    set val3 [drscan AG10K.tap 512 $page3 -endstate DRSHIFT]
    set val4 [drscan AG10K.tap 512 $page4 -endstate RUN/IDLE]
    runtest 10
    sflash_cmd 0x4 0x0 8
    # 输出为2
    # puts "status :[hex_to_byte [sflash_cmd 0x5 0x0 40] 4]"
    return $val1;
}


set vv  [sflash_cmd 0x5a 0x0 896]
set arr [hex_to_byte $vv]
set arr [lreplace $arr 0 4]
puts $arr

puts "flash sector type1 size:[expr {1<<[lindex $arr 0x4c]}]"
puts "flash sector type2 size:[expr {1<<[lindex $arr 0x4e]}]"
puts "flash sector type3 size:[expr {1<<[lindex $arr 0x50]}]"
puts "flash sector type4 size:[expr {1<<[lindex $arr 0x52]}]"

puts "Vcc max:[format "%04x" [expr [lindex $arr 0x60]|([lindex $arr 0x61]<<8)]]"
puts "Vcc min:[format "%04x" [expr [lindex $arr 0x62]|([lindex $arr 0x63]<<8)]]"

puts "read flash data:"

set arr [hex_to_byte [sflash_read 0xf0 0x20]]
foreach b $arr {
    set hex [format "%02x" $b]
    puts $hex;
}

# 擦除一页
# sflash_erase 0x0

# sflash_program_begin 0x0
# sflash_send32 0x12345678
# sflash_program_end 0xabcdef12

runtest 10000

puts [sflash_read 0x00 4096]

# puts [sflash_cmd 0x5a 0x0 896]


